#include <nxos.h>

/* init envline for environment var */
#define InitEnvLine "PATH=/Applications:/System/Applications:/System/Service"

struct SystemService 
{
    char *file;
    char *cmd;
    char *env;
    int delay; /* service start delay(ms) */
};

NX_PRIVATE struct SystemService SystemServiceTable[] = 
{
    // {"FileSystem.xapp", "FileSystem.xapp", InitEnvLine, 100},
    {"PowerBox.xapp", "PowerBox.xapp", InitEnvLine, 0},
};

void InitStdio()
{
    NX_Solt fd, stdfd;
    fd = NX_FileOpen("/System/Device/console", NX_FILE_RDONLY, 0);
    NX_ASSERT(fd >= 0);
    stdfd = NX_SoltCopyTo(NX_ThreadGetCurrent(), fd, 0);
    NX_ASSERT(stdfd == 0);
    if (stdfd != 0)
    {
        NX_ProcessExit(0);
    }
    NX_FileClose(fd);

    fd = NX_FileOpen("/System/Device/console", NX_FILE_WRONLY, 0);
    NX_ASSERT(fd >= 0);
    stdfd = NX_SoltCopyTo(NX_ThreadGetCurrent(), fd, 1);
    NX_ASSERT(stdfd == 1);
    if (stdfd != 1)
    {
        NX_ProcessExit(0);
    }

    stdfd = NX_SoltCopyTo(NX_ThreadGetCurrent(), fd, 2);
    NX_ASSERT(stdfd == 2);
    if (stdfd != 2)
    {
        NX_ProcessExit(0);
    }
    NX_FileClose(fd);
}

/**
 * start service
 * start shell/gui
 */

NX_Error NX_Main(char *cmdline, char *envline)
{
    int i;
    struct SystemService *serv;
    NX_U32 exitCode;
    NX_Solt solt;
    NX_Printf("UserLand start.\n");

    InitStdio();

    for (i = 0; i < NX_ARRAY_SIZE(SystemServiceTable); i++)
    {
        serv = &SystemServiceTable[i];
        solt = NX_ProcessLaunch(serv->file, 0, &exitCode, serv->cmd, serv->env);
        if (solt == NX_SOLT_INVALID_VALUE)
        {
            NX_Printf("UserLand: start %s failed with state %s.\n", serv->cmd, NX_ErrorToString(NX_ErrorGet()));
        }
        else
        {
            NX_Printf("UserLand: start [%s] success!\n", serv->cmd);
            NX_ThreadSleep(serv->delay);
            NX_Printf("UserLand: dealy [%s] with %d ms done.\n", serv->cmd, serv->delay);
        }
    }
    return NX_EOK;
}
